package com.west.xu.redis.service.impl;

import com.west.xu.redis.service.IRedisServie;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service(value = "redisService")
public class RedisServieImp implements IRedisServie {


    private final String KEY_VALUE_CACHE = "WEST_CACHE";
    private final String KEY_MAP_CACHE = "WEST_MP";

    @Autowired
    private RedisTemplate cacheRedisTemplate;
    @Autowired
    private StringRedisTemplate cacheStringRedisTemplate;


    public List<Object> cacheBatchData(List<String> dataList) {
        List<Object> resultList = cacheRedisTemplate.executePipelined(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                String key = null;
                String data = null;
                for (int n = 0; n < dataList.size(); n++) {
                    key = "Key_" + n;
                    data = dataList.get(n);
                    connection.stringCommands().set(key.getBytes(), data.getBytes());
                    connection.expire(key.getBytes(), 60);
                }

                Map<byte[], byte[]> map = new HashMap<>();
                for (int n = 0; n < dataList.size(); n++) {
                    key = "Key_" + n;
                    data = dataList.get(n);
                    map.put(key.getBytes(), data.getBytes());
                }
                connection.hashCommands().hMSet(KEY_MAP_CACHE.getBytes(), map);
                connection.expire(KEY_MAP_CACHE.getBytes(), 60);

                //Must Return Null
                return null;
            }
        });
        return resultList;
    }

    @Override
    public void cacheMsg(String msg) {
        cacheRedisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations operations) throws DataAccessException {
                operations.multi();

                BoundValueOperations<String, String> valueOperations = cacheRedisTemplate.boundValueOps(KEY_VALUE_CACHE);
                valueOperations.set(msg);

                operations.exec();
                return true;
            }
        });
    }

    @Override
    public Map fetchDataMap() {
        BoundHashOperations hashOperations = cacheRedisTemplate.boundHashOps(KEY_MAP_CACHE);
        return hashOperations.entries();
    }

    @Override
    public String fetchMsg() {
        BoundValueOperations<String, String> valueOperations = cacheRedisTemplate.boundValueOps(KEY_VALUE_CACHE);
        return valueOperations.get();
    }

    @Override
    public void publishMsg(String channel, String msg) {
        cacheStringRedisTemplate.convertAndSend(channel, msg);
    }
}
